/**estado(ph,pv,ca,pl)   
 *
 * platano en el centro de la habitación arriba
 * el mono entra por la puerta en el suelo
 * la caja al lado de la ventana en el suelo
 * El mono tiene que alcanzar el platano
 *  
 * POSICION HORIZONTAL (ph), 
 * Puerta = 0
 * Centro = 1
 * Ventana = 2
 *
 * POSICION VERTICAL (pv)
 * Suelo = 0
 * ARRIBA = 1
 
 
 * POSICION CAJA (ca)
 * Puerta = 0
 * Centro = 1
 * Ventana = 2
 *  

 * 
 * PLATANO (pl)
 * No Tiene= 0
 * Tiene = 1
 */ 

package Problemas;

import Busquedas.Estado;

public class Mono extends Problema{
	
	
	
	public static final int PUERTA = 0;
	
	public static final int CENTRO = 1;
	
	public static final int VENTANA = 2;
	
	public static final int SUELO = 0;
	
	public static final int ARRIBA = 1;
	
	private int ph;
	
	private int pv;
	
	private int ca;
	
	private int pl;

	
	/**
	 * Constructor de la clase
	 */
	public Mono(){
		int paramInicial[] = {0,0,2,0};
        int paramObjetivo[] = {1,1,1,1};
		Estado inicial = new Estado(paramInicial);
        Estado []objetivo = new Estado[1];
        objetivo[0] = new Estado(paramObjetivo);
		
        String[] nombresOperadores = {"padre","andarPuerta","andarCentro","andarVentana",
		 					"subirseCaja","empujarPuerta","empujarCentro",
									"empujarVentana","cogerPlatano"};
		int[] costeOperadores = {1,1,1,1,1,1,1,1};
		this.inicializa(inicial,objetivo,8,nombresOperadores,costeOperadores);
	}
	
	

	public void asignaParametros(Estado actual){
		ph = actual.getParametro(0);
		pv = actual.getParametro(1);
		ca = actual.getParametro(2);
		pl = actual.getParametro(3);
	}
	

	public Estado andar(int lugar){
		if (pv != ARRIBA && ph != lugar){
			int[] param = {lugar,SUELO,ca,pl};
			return new Estado(param);
		}
		return null;
	}
	
	

	public Estado subirseCaja(){
		if (pv != ARRIBA && ph == ca){
			int[] param = {ph,ARRIBA,ca,pl};
			return new Estado(param);
		}
		return null;
	}

	
	

	public Estado empujarCaja(int lugar){
		if (pv != ARRIBA && ca != lugar && ph == ca){
			int[] param = {lugar,SUELO,lugar,pl};
			return new Estado(param);
		}
		return null;
	}
	
	

	public Estado cogerPlatano(){
		if (ph == CENTRO && pv == ARRIBA && ca == CENTRO){
			int[] param = {ph,pv,ca,1};
			return new Estado(param);
		}
		return null;
		
	}
	
	
	
	/* (non-Javadoc)
	 * @see Problema#aplicaOperador(Estado, int)
	 */
	public Estado aplicaOperador(Estado actual,int operador){
		asignaParametros(actual);
		Estado siguiente = null;
		switch(operador){
		case 0:
			siguiente = andar(PUERTA);
			break;
		case 1:
			siguiente = andar(CENTRO);
			break;
		case 2:
			siguiente = andar(VENTANA);
			break;
		case 3:
			siguiente = subirseCaja();
			break;
		case 4:
			siguiente = empujarCaja(PUERTA);
			break;
		case 5:
			siguiente = empujarCaja(CENTRO);
			break;
		case 6:
			siguiente = empujarCaja(VENTANA);
			break;
		case 7:
			siguiente = cogerPlatano();
			break;
		}
		return siguiente;
	}
	

	
	/* (non-Javadoc)
	 * @see Problema#estadoFinal(Estado)
	 */
	/*boolean estadoFinal(Estado actual){
		return actual.getParametro(3) == 1;
	}
*/
	//@Override
	public int getOperadorInverso(int op) {
		return -1;
	}

        public int funcionHeuristica(Estado estado){

         //movientos hasta el platano
         asignaParametros(estado);

		if (ph == 0) return 5;
		if (ph == 2 && ca == 1) return 3;
		if (ph == 2 && ca == 2 && pv==1) return 4;
		if (ph == 2 && ca == 2 && pv==0) return 3;
        if (ph == 1 && ca != 1) return 4;
        if (ph == 1 && pv==0 && ca == 1) return 2;
        if (ph == 1 && pv==1 && pl==0) return 1;
		if (ph == 1 && pv==1 && pl==1) return 0;
		return 6;



	}

}
